package com.avalon.shop.service;

import com.avalon.core.exception.AvalonException;
import com.avalon.core.model.RecordRow;
import com.avalon.core.util.JacksonUtil;
import com.avalon.core.util.ObjectUtils;
import com.avalon.core.util.RestTemplateUtils;
import com.avalon.shop.ShopContext;
import com.avalon.shop.config.ShopConfig;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class OrderService {
    private final ShopConfig shopConfig;
    private final ShopContext shopContext;
    private final String serviceName = "pet.order";

    public OrderService(ShopConfig shopConfig, ShopContext shopContext) {
        this.shopConfig = shopConfig;
        this.shopContext = shopContext;
    }

    public void addOrder(Map<String, Object> value) {
        HashMap<String, Object> param = new HashMap<>();
        param.put("serviceName", serviceName);
        param.put("value", value);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/add",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
        } else {
            log.error("addOrder 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }

    private final String fields = "id,orderNo,state,totalAmount," +
            "isPay,isSend,isReceive, isComment,isCancel," +
            "expressNo,expressCompany,expressFree,expressState," +
            "createTime,addressDetail,phone,receiverName," +
            "orderDetail.commodityId.firstUrl,orderDetail.count," +
            "orderDetail.id,orderDetail.commodityId.id," +
            "orderDetail.commodityId.name,orderDetail.price," +
            "orderDetail.count," +
            "orderDetail.price,orderDetail.total";

    /**
     * 获取未完成的所有订单
     */
    public List<Map> getOrderStateAll(Integer userId, String state) {
        HashMap<String, Object> param = new HashMap<>();
        param.put("fields", fields);
        if ("all".equals(state)) {
            param.put("rpnCondition", "(=,userId," + userId + ")");
        } else {
            param.put("rpnCondition", "(&,(=,userId," + userId + "),(=,state," + state + "))");
        }

        param.put("serviceName", serviceName);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/get/all",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            List<Map> maps = JacksonUtil.convert2Object(responseEntity.getBody(),
                    new TypeReference<List<Map>>() {
                    });
            return maps;
        } else {
            log.error("getOrderAll 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }

    public Map<String, Object> getOrderStateCount(Integer userId) {
        List<Map> wait = getOrderStateAll(userId, "wait");
        List<Map> send = getOrderStateAll(userId, "send");
        List<Map> receive = getOrderStateAll(userId, "receive");
        List<Map> comment = getOrderStateAll(userId, "comment");
        List<Map> cancel = getOrderStateAll(userId, "cancel");
        Map<String, Object> result = new HashMap<>();
        result.put("wait", wait.size());
        result.put("send", send.size());
        result.put("receive", receive.size());
        result.put("comment", comment.size());
        result.put("cancel", cancel.size());
        return result;
    }

    public RecordRow getOrderDetail(Integer id) {
        log.info("getOrderDetail: id={}", id);
        HashMap<String, Object> param = new HashMap<>();
        param.put("fields", fields);
        param.put("serviceName", serviceName);
        param.put("rpnCondition", "(=,id," + id + ")");
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        headers.put("token", shopContext.getBackToken());
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/get/detail",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            RecordRow recordRow = JacksonUtil.convert2Map(responseEntity.getBody());
            if (recordRow.isEmpty()) {
                throw new AvalonException("订单不存在");
            }
            return recordRow;
        }
        throw new AvalonException("查询订单发生错误");
    }

    /**
     * 确认收货
     *
     * @param id
     */
    public void orderReceiveSure(Integer id) {
        log.info("orderReceiveSure: id={}", id);
        HashMap<String, Object> param = new HashMap<>();
        param.put("id", id);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        headers.put("token", shopContext.getBackToken());
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/order/receive/sure",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            return;
        }
        throw new AvalonException("确认收货时发生错误");
    }

    public void orderComment(Integer id) {
        log.info("orderComment: id={}", id);
        HashMap<String, Object> param = new HashMap<>();
        param.put("id", id);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        headers.put("token", shopContext.getBackToken());
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/order/comment/complete",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            return;
        }
        throw new AvalonException("提交评价时发生错误");
    }

    /**
     * 取消订单
     *
     * @param id                 订单id
     * @param backExpressNo      快递单号
     * @param backExpressCompany 快递公司
     * @param backReason         取消原因
     */
    public void orderCancel(Integer id, String backExpressNo, String backExpressCompany, String backReason) {
        log.info("orderCancel: id={}", id);
        HashMap<String, Object> param = new HashMap<>();
        param.put("id", id);
        param.put("backExpressNo", backExpressNo);
        param.put("backExpressCompany", backExpressCompany);
        param.put("backReason", backReason);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        headers.put("token", shopContext.getBackToken());
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/order/custom/cancel",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            return;
        }
        throw new AvalonException("申请取消订单时发生错误");
    }
}
